# -*- coding: utf-8 -*-
import os
import json
import logging
from flask import Flask, request
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime, timedelta
from utils import userzkem, attendance, useronboard, zkemdataclean, deleteuser, zkemdataclear
from flask_apscheduler import APScheduler
from flask_cors import CORS
from multiprocessing import Process

from utils.userface import delete_user
# 创建Flask应用
app = Flask(__name__)
CORS(app)

# 初始化全局变量
class Config(object):
    SCHEDULER_API_ENABLED = True
scheduler = APScheduler()

# 配置日志
def setup_logging():
    """配置日志系统"""
    current_dir = os.path.dirname(os.path.abspath(__file__))
    target_dir = os.path.join(current_dir, "logs")
    # 确保日志目录存在
    os.makedirs(target_dir, exist_ok=True)
    log_filename = os.path.join(target_dir, "mainsetup_schedule.log")
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler(log_filename, encoding='utf-8'),
            logging.StreamHandler()
        ]
    )
    return logging.getLogger(__name__)

logger = setup_logging()


# 修改任务 ID 保证唯一
@scheduler.task('cron', id='attendjob_08_45', day='*', hour='08', minute='45', second='0', timezone='Asia/Shanghai')
def attendjob_08_45():
    attendjob("08:45")

@scheduler.task('cron', id='attendjob_14_00', day='*', hour='14', minute='00', second='0', timezone='Asia/Shanghai')
def attendjob_14_00():
    attendjob("14:00")

@scheduler.task('cron', id='attendjob_19_00', day='*', hour='19', minute='00', second='0', timezone='Asia/Shanghai')
def attendjob_19_00():
    attendjob("19:00")

@scheduler.task('cron', id='attendjob_23_00', day='*', hour='23', minute='00', second='0', timezone='Asia/Shanghai')
def attendjob_23_00():
    attendjob("23:00")

@scheduler.task('cron', id='attendjob_02_00', day='*', hour='02', minute='00', second='0', timezone='Asia/Shanghai')
def attendjob_02_00():
    attendjob("02:00")


@scheduler.task('cron', id='judge_attendance_job_04_00', day='03', hour='04', minute='00', second='0', timezone='Asia/Shanghai')
def judge_attendance_job():
    """考勤数据清洗任务"""
    today = datetime.now()
    # 本月1号
    first_day_this_month = today.replace(day=1)
    # 上个月最后一天 = 本月1号 - 1天
    end_date = first_day_this_month - timedelta(days=1)
    # 上个月第一天 = 上个月最后一天.replace(day=1)
    start_date = end_date.replace(day=1)

    current_date = start_date
    try:
        while current_date <= end_date:
            logger.info(f"开始执行考勤数据清洗任务: {current_date}")
            zkemdataclean.start(current_date, True)
            logger.info(f"考勤考勤数据清洗完成: {current_date}")
            current_date += timedelta(days=1)
    except Exception as e:
        logger.error(f"考勤考勤数据清洗失败: {str(e)}")

@scheduler.task('cron', id='judge_attendance_job_10_00', day='*', hour='10', minute='50', second='0', timezone='Asia/Shanghai')
def judge_attendance_job_10_00():
    """考勤数据清洗任务"""
    logger.info("开始执行考勤数据清洗任务")
    try:
        target_date = datetime.now() - timedelta(days=1)
        zkemdataclean.start(target_date, False)
        logger.info("考勤考勤数据清洗完成")
    except Exception as e:
        logger.error(f"考勤考勤数据清洗失败: {str(e)}")

@scheduler.task( 'cron', id='weekly_sunday_job_04_00', day_of_week='sun', hour='03', minute='00', second='0', timezone='Asia/Shanghai' )
def clear_device_data():
    print("每周日 03:00 执行任务")
    clear_time = datetime.now() - timedelta(days=45)
    clear_time_str = clear_time.strftime('%Y-%m-%d %H:%M:%S')
    zkemdataclear.start(clear_time_str)

#数据迁移
def date_migrate():
    logger.info("开始数据迁移")
    try:
        target_date = datetime.now()
        zkemdataclean.date_migrate(target_date)
        logger.info("数据迁移完成")
    except Exception as e:
        logger.error(f"数据迁移失败: {str(e)}")

# 任务执行函数
def attendjob(time_of_day):
    try:
        logger.info(f"开始执行任务 - {time_of_day}")
        attendance.startmain()
        date_migrate()
        logger.info(f"任务完成 - {time_of_day}")
    except Exception as e:
        logger.error(f"任务执行失败 - {time_of_day}: {str(e)}")


# 创建线程池执行任务
executor = ThreadPoolExecutor(max_workers=9)

# 同步接口-员工人脸变更
@app.route('/userzkem', methods=['GET', 'POST'])
def UserZKTeco():
    try:
        data = json.loads(request.get_data(as_text=True))
        logger.info(f"Received data: {data}")
        resu = {'code': 200, 'result': 'success!'}

        # 使用线程池执行任务
        # executor.submit(userzkem.start, data)
        Process(target=userzkem.start, args=(data,)).start()
        return json.dumps(resu, ensure_ascii=False)
    except Exception as e:
        logger.error(f"接口处理异常: {str(e)}")
        return json.dumps({'code': 500, 'result': str(e)}), 500


# 同步接口-员工信息
@app.route('/useronboard', methods=['GET', 'POST'])
def UserOnboard():
    try:
        data = json.loads(request.get_data(as_text=True))
        logger.info(f"Received data: {data}")
        resu = {'code': 200, 'result': 'success!'}
        # 使用线程池执行任务
        # executor.submit(useronboard.start, data)
        Process(target=useronboard.start, args=(data,)).start()
        return json.dumps(resu, ensure_ascii=False)
    except Exception as e:
        logger.error(f"接口处理异常: {str(e)}")
        return json.dumps({'code': 500, 'result': str(e)}), 500

# 删除接口-员工删除
@app.route('/deleteuser', methods=['GET', 'POST'])
def DeleteUser():
    try:
        data = json.loads(request.get_data(as_text=True))
        logger.info(f"Received data: {data}")
        resu = {'code': 200, 'result': 'success!'}
        # 使用线程池执行任务
        # executor.submit(deleteuser.start, data)
        Process(target=deleteuser.start, args=(data,)).start()
        return json.dumps(resu, ensure_ascii=False)
    except Exception as e:
        logger.error(f"接口处理异常: {str(e)}")
        return json.dumps({'code': 500, 'result': str(e)}), 500


@app.route("/clearChcekData", methods=['GET'])
def clear_check_data():
    clear_time_str = request.args.get('clearTime')
    ip = request.remote_addr
    logger.info(f"Received data: {ip}, {clear_time_str}")
    if not clear_time_str:
        return  json.dumps({'code': 400, 'result': '缺少参数!'}, ensure_ascii=False)
    try:
        clear_time = datetime.strptime(clear_time_str, '%Y-%m-%d %H:%M:%S')
    except ValueError:
        return  json.dumps({'code': 400, 'result': '参数格式不正确!'}, ensure_ascii=False)

    limit_time = datetime.now() - timedelta(days=45)
    if clear_time > limit_time:
        return  json.dumps( {'code': 400, 'result': '清除时间不能晚于当前时间前45天!'}, ensure_ascii=False)
    zkemdataclear.start(clear_time_str)
    resu = {'code': 200, 'result': '成功清除设备数据!'}
    return json.dumps(resu, ensure_ascii=False)

@app.route("/cleanChcekData", methods=['GET'])
def clean_check_data():
    start_time_str = request.args.get('startTime')
    end_time_str = request.args.get('endTime')
    ip = request.remote_addr
    logger.info(f"Received data: {ip}, {start_time_str} {end_time_str}")

    # 参数不能为空
    if not start_time_str or not end_time_str:
        return  json.dumps({'code': 400, 'result': '缺少参数!'}, ensure_ascii=False)
    # 校验时间格式
    try:
        start_time = datetime.strptime(start_time_str, '%Y-%m-%d')
        end_time = datetime.strptime(end_time_str, '%Y-%m-%d')
    except ValueError:
        return  json.dumps({'code': 400, 'result': '参数格式不正确!'}, ensure_ascii=False)
    # 校验开始时间不得晚于结束时间
    if start_time > end_time:
        return json.dumps({'code': 400, 'result': '开始时间不得晚于结束时间'}, ensure_ascii=False)
    # 遍历每一天
    current_date = start_time
    while current_date <= end_time:
        print(current_date.strftime("%Y-%m-%d"))
        zkemdataclean.start(current_date, False)
        current_date += timedelta(days=1)
    resu = {'code': 200, 'result': '清洗成功，请重新同步OA系统!'}
    return json.dumps(resu, ensure_ascii=False)

# 新增接口：根据手机号获取打卡记录
@app.route("/getCheckInRecordsByPhone", methods=['GET'])
def get_check_attendance():
    tel = request.args.get('tel')
    date_str = request.args.get('date')
    ip = request.remote_addr
    logger.info(f"Received data: {ip}, tel={tel}, date={date_str}")

    if not tel:
        return json.dumps({'code': 400, 'result': '缺少必要参数 tel'}, ensure_ascii=False)
    try:
        # 如果没有提供 date 参数，默认查最近 7 天
        if not date_str:
            end_date = datetime.now()
            start_date = end_date - timedelta(days=7)
            # 获取时间戳范围（秒级）
            start_ts = int(start_date.timestamp())
            end_ts = int(end_date.timestamp())

            data = useronboard.get_attendance_records_by_phone(tel, start_ts, end_ts)
        else:
            try:
                date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
            except ValueError:
                raise ValueError("日期格式错误，正确格式为 YYYY-MM-DD")
            # 获取当天的时间戳范围
            start_of_day = datetime.combine(date_obj, datetime.min.time())
            end_of_day = datetime.combine(date_obj, datetime.max.time())
            start_ts = int(start_of_day.timestamp())
            end_ts = int(end_of_day.timestamp())

            data = useronboard.get_attendance_records_by_phone(tel, start_ts, end_ts)

        return json.dumps({'code': 200, 'data': data}, ensure_ascii=False)

    except ValueError as ve:
        return json.dumps({'code': 400, 'result': str(ve)}, ensure_ascii=False)
    except Exception as e:
        logger.error(f"查询失败: {str(e)}")
        return json.dumps({'code': 500, 'result': str(e)}, ensure_ascii=False)

if __name__ == '__main__':
    app.config.from_object(Config())

    scheduler.api_enabled = True
    scheduler.init_app(app)
    scheduler.start()

    # 启动Flask应用
    app.run(port=6980, host='0.0.0.0', threaded=True, debug=False)
